#include "../logs/log.h"
#include <chrono>

void bench(const std::string &logger_name, size_t thr_cnt, size_t msg_cnt, size_t msg_len)
{
    // 1. 获取日志器
    log::Logger::ptr logger = log::getLogger(logger_name);
    if (logger == nullptr)
        return;
    std::cout << "测试日志：" << msg_cnt << "条，总大小：" << (msg_cnt*msg_len)/1024 << "KB\n";
    // 2. 指定日志消息长度
    std::string msg(msg_len - 1, 'a');
    // 3. 创建指定长度的日志消息
    size_t msg_avg_cnt = msg_cnt / thr_cnt; // 每个线程处理的日志数量
    std::vector<double> sum(thr_cnt);  // 每个线程处理日志的时间
    std::vector<std::thread> threads;
    for (int i = 0; i < thr_cnt; i++)
    {
        threads.emplace_back([&, i](){
            // 4. 线程函数内部开始计时
            auto start = std::chrono::high_resolution_clock::now();
            // 5. 开始循环写日志
            for(int j = 0; j < msg_avg_cnt; j++)
            {
                logger->fatal(__FILE__, __LINE__,"%s", msg.c_str());
            }
            // 6. 线程函数内部结束计时
            auto end = std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> gap = end - start;
            sum[i] = gap.count();
            std::cout << "线程" << i << "：" << "\t输出数量：" << msg_avg_cnt << "\t耗时：" << gap.count() << std::endl;
        });
    }
    for(int i = 0; i < thr_cnt; i++)
    threads[i].join();
    // 7. 计算总耗时
    double max_time = sum[0];
    for(auto t: sum) 
        max_time = max_time > t ? max_time : t;
    // 8. 进行输出打印
    std::cout << "总耗时："<< max_time << std::endl;
    std::cout << "\t每秒输出日志数量：" << msg_cnt / max_time << "条\n";
    std::cout << "\t每秒输出日志大小：" << msg_cnt*msg_len / (max_time * 1024) << "Kb\n";
}

void sync_bench()
{
    std::unique_ptr<log::LoggerBuilder> builder(new log::GlobalLoggerBuilder());
    builder->buildLoggerName("async_logger");
    builder->buildLoggerType(log::LoggerType::SYNC_LOGGER);
    builder->buildFormatter();
    builder->buildLoggerLevel(log::Level::value::DEBUG);
    builder->buildSink<log::FileSink>("./logfile/sync.log");
    builder->buildEnableUnSafeAsync();
    auto logger = builder->build();
    std::cout << logger->name() << std::endl;
    bench(logger->name(), 4, 1000000, 100);
}
void async_bench()
{
    std::unique_ptr<log::LoggerBuilder> builder(new log::GlobalLoggerBuilder());
    builder->buildLoggerName("async_logger");
    builder->buildLoggerType(log::LoggerType::ASYNC_LOGGER);
    builder->buildFormatter();
    builder->buildLoggerLevel(log::Level::value::DEBUG);
    builder->buildSink<log::FileSink>("./logfile/sync.log");
    builder->buildEnableUnSafeAsync();
    auto logger = builder->build();
    std::cout << logger->name() << std::endl;
    bench(logger->name(), 4, 1000000, 100);
}
int main()
{
    sync_bench();
    // async_bench();
    return 0;
}